package com.nti56.springboot.config.database;

import com.alibaba.druid.pool.DruidDataSource;
import com.nti56.springboot.config.interceptor.CCUUInterceptor;
import com.nti56.springboot.config.interceptor.SqlInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;


@Configuration
@MapperScan(basePackages = "com.nti56.springboot.mapper.tmsmapper", sqlSessionTemplateRef = "tmsSqlSessionTemplate")
public class TMSDatabaseConfig {
	
	@Autowired
    private Environment env;
	
	@Value("${spring.datasource.database-tms.jdbc-url}")  
    private String dbUrl;  
    @Value("${spring.datasource.database-tms.username}")  
    private String username;  
    @Value("${spring.datasource.database-tms.password}")  
    private String password;  
    @Value("${spring.datasource.database-tms.driver-class-name}")  
    private String driverClassName;  
    @Value("${spring.datasource.database-tms.initialSize}")  
    private int initialSize;  
    @Value("${spring.datasource.database-tms.minIdle}")  
    private int minIdle;  
    @Value("${spring.datasource.database-tms.maxActive}")  
    private int maxActive;  
    @Value("${spring.datasource.database-tms.maxWait}")  
    private int maxWait;  
    @Value("${spring.datasource.database-tms.timeBetweenEvictionRunsMillis}")  
    private int timeBetweenEvictionRunsMillis;  
    @Value("${spring.datasource.database-tms.minEvictableIdleTimeMillis}")  
    private int minEvictableIdleTimeMillis;  
    @Value("${spring.datasource.database-tms.validationQuery}")  
    private String validationQuery;  
    @Value("${spring.datasource.database-tms.testWhileIdle}")  
    private boolean testWhileIdle;  
    @Value("${spring.datasource.database-tms.testOnBorrow}")  
    private boolean testOnBorrow;  
    @Value("${spring.datasource.database-tms.testOnReturn}")  
    private boolean testOnReturn;  
    @Value("${spring.datasource.database-tms.poolPreparedStatements}")  
    private boolean poolPreparedStatements;  
    @Value("${spring.datasource.database-tms.maxPoolPreparedStatementPerConnectionSize}")  
    private int maxPoolPreparedStatementPerConnectionSize;  
    @Value("${spring.datasource.database-tms.filters}")  
    private String filters;  
    @Value("${spring.datasource.database-tms.connectionProperties}")  
    private String connectionProperties;  
    @Value("${spring.datasource.database-tms.useGlobalDataSourceStat}")  
    private boolean useGlobalDataSourceStat;  
	
	//根据application.properteis系统配置文件中,对应属性的前缀,指明使用其对应的数据
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource.database-tms")
	@Primary
	public DataSource tmsDataSource() {
		//使用下面 这行代码初始化的datasource druid 页面不打印SQL
		//return DataSourceBuilder.create().build();
		
		DruidDataSource datasource = new DruidDataSource();  
        datasource.setUrl(this.dbUrl);  
        datasource.setUsername(username);  
        datasource.setPassword(password);  
        datasource.setDriverClassName(driverClassName);  
  
        //configuration  
        datasource.setInitialSize(initialSize);  
        datasource.setMinIdle(minIdle);  
        datasource.setMaxActive(maxActive);  
        datasource.setMaxWait(maxWait);  
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
        datasource.setValidationQuery(validationQuery);  
        datasource.setTestWhileIdle(testWhileIdle);  
        datasource.setTestOnBorrow(testOnBorrow);  
        datasource.setTestOnReturn(testOnReturn);  
        datasource.setPoolPreparedStatements(poolPreparedStatements);  
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
        datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);  
        try {  
            datasource.setFilters(filters);  
        } catch (SQLException e) {  
            System.err.println("druid configuration initialization filter: "+ e);  
        }  
        datasource.setConnectionProperties(connectionProperties);  
        return datasource;  
	}
 
	@Bean
	@DependsOn("tmsDataSource")
	@Primary
	public SqlSessionFactory tmsSqlSessionFactory() throws Exception {
		String mapperLocations = env.getProperty("mybatis.tms.mapperLocations");
		String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
		boolean showSqlCost = Boolean.valueOf(env.getProperty("mybatis.showSqlCost"));
		SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
		factoryBean.setDataSource(tmsDataSource());
		factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
								.getResources(mapperLocations));
		factoryBean.setTypeAliasesPackage(typeAliasesPackage);
		//是否打印SQL执行时间
		if(showSqlCost){
			factoryBean.setPlugins(new Interceptor[] {new SqlInterceptor(),new CCUUInterceptor()});
		}else {
			factoryBean.setPlugins(new Interceptor[] {new CCUUInterceptor()});
		}
		return factoryBean.getObject();
	}
	
	@Bean(name = "tmsTransactionManager")
    @Primary
    public DataSourceTransactionManager testTransactionManager(@Qualifier("tmsDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
	
	/**
	 * DefaultSqlSession和SqlSessionTemplate都实现了SqlSession,但我们
	 * 注入线程安全的SqlSessionTemplate,而不使用默认的线程不安全的DefaultSqlSession
	 *
	 * @Date 2019年5月10日 上午10:46:39
	 */
	@Bean
	@DependsOn("tmsSqlSessionFactory")
	@Primary
	public SqlSessionTemplate tmsSqlSessionTemplate() throws Exception {
		SqlSessionTemplate template = new SqlSessionTemplate(tmsSqlSessionFactory());
		return template;
	}
}
